{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 导入工具包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np  # 矩阵操作\n",
    "import pandas as pd # SQL数据处理\n",
    "\n",
    "from sklearn.metrics import r2_score  #评价回归预测模型的性能\n",
    "from sklearn.metrics import mean_squared_error\n",
    "\n",
    "import matplotlib.pyplot as plt   #画图\n",
    "import seaborn as sns\n",
    "\n",
    "# 图形出现在Notebook里而不是新窗口\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据探索"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>instant</th>\n",
       "      <th>dteday</th>\n",
       "      <th>season</th>\n",
       "      <th>yr</th>\n",
       "      <th>mnth</th>\n",
       "      <th>holiday</th>\n",
       "      <th>weekday</th>\n",
       "      <th>workingday</th>\n",
       "      <th>weathersit</th>\n",
       "      <th>temp</th>\n",
       "      <th>atemp</th>\n",
       "      <th>hum</th>\n",
       "      <th>windspeed</th>\n",
       "      <th>casual</th>\n",
       "      <th>registered</th>\n",
       "      <th>cnt</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>2011-01-01</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>6</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.344167</td>\n",
       "      <td>0.363625</td>\n",
       "      <td>0.805833</td>\n",
       "      <td>0.160446</td>\n",
       "      <td>331</td>\n",
       "      <td>654</td>\n",
       "      <td>985</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>2011-01-02</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.363478</td>\n",
       "      <td>0.353739</td>\n",
       "      <td>0.696087</td>\n",
       "      <td>0.248539</td>\n",
       "      <td>131</td>\n",
       "      <td>670</td>\n",
       "      <td>801</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>2011-01-03</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.196364</td>\n",
       "      <td>0.189405</td>\n",
       "      <td>0.437273</td>\n",
       "      <td>0.248309</td>\n",
       "      <td>120</td>\n",
       "      <td>1229</td>\n",
       "      <td>1349</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>2011-01-04</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.200000</td>\n",
       "      <td>0.212122</td>\n",
       "      <td>0.590435</td>\n",
       "      <td>0.160296</td>\n",
       "      <td>108</td>\n",
       "      <td>1454</td>\n",
       "      <td>1562</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>2011-01-05</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.226957</td>\n",
       "      <td>0.229270</td>\n",
       "      <td>0.436957</td>\n",
       "      <td>0.186900</td>\n",
       "      <td>82</td>\n",
       "      <td>1518</td>\n",
       "      <td>1600</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   instant      dteday  season  yr  mnth  holiday  weekday  workingday  \\\n",
       "0        1  2011-01-01       1   0     1        0        6           0   \n",
       "1        2  2011-01-02       1   0     1        0        0           0   \n",
       "2        3  2011-01-03       1   0     1        0        1           1   \n",
       "3        4  2011-01-04       1   0     1        0        2           1   \n",
       "4        5  2011-01-05       1   0     1        0        3           1   \n",
       "\n",
       "   weathersit      temp     atemp       hum  windspeed  casual  registered  \\\n",
       "0           2  0.344167  0.363625  0.805833   0.160446     331         654   \n",
       "1           2  0.363478  0.353739  0.696087   0.248539     131         670   \n",
       "2           1  0.196364  0.189405  0.437273   0.248309     120        1229   \n",
       "3           1  0.200000  0.212122  0.590435   0.160296     108        1454   \n",
       "4           1  0.226957  0.229270  0.436957   0.186900      82        1518   \n",
       "\n",
       "    cnt  \n",
       "0   985  \n",
       "1   801  \n",
       "2  1349  \n",
       "3  1562  \n",
       "4  1600  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# path to where the data lies\n",
    "data = pd.read_csv(\"day.csv\")\n",
    "\n",
    "#通过观察前5行，了解数据每列（特征）的概况\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(731, 16)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 特征工程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>season</th>\n",
       "      <th>yr</th>\n",
       "      <th>mnth</th>\n",
       "      <th>holiday</th>\n",
       "      <th>weekday</th>\n",
       "      <th>workingday</th>\n",
       "      <th>weathersit</th>\n",
       "      <th>temp</th>\n",
       "      <th>atemp</th>\n",
       "      <th>hum</th>\n",
       "      <th>windspeed</th>\n",
       "      <th>cnt</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>6</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.344167</td>\n",
       "      <td>0.363625</td>\n",
       "      <td>0.805833</td>\n",
       "      <td>0.160446</td>\n",
       "      <td>985</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>0.363478</td>\n",
       "      <td>0.353739</td>\n",
       "      <td>0.696087</td>\n",
       "      <td>0.248539</td>\n",
       "      <td>801</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.196364</td>\n",
       "      <td>0.189405</td>\n",
       "      <td>0.437273</td>\n",
       "      <td>0.248309</td>\n",
       "      <td>1349</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.200000</td>\n",
       "      <td>0.212122</td>\n",
       "      <td>0.590435</td>\n",
       "      <td>0.160296</td>\n",
       "      <td>1562</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.226957</td>\n",
       "      <td>0.229270</td>\n",
       "      <td>0.436957</td>\n",
       "      <td>0.186900</td>\n",
       "      <td>1600</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   season  yr  mnth  holiday  weekday  workingday  weathersit      temp  \\\n",
       "0       1   0     1        0        6           0           2  0.344167   \n",
       "1       1   0     1        0        0           0           2  0.363478   \n",
       "2       1   0     1        0        1           1           1  0.196364   \n",
       "3       1   0     1        0        2           1           1  0.200000   \n",
       "4       1   0     1        0        3           1           1  0.226957   \n",
       "\n",
       "      atemp       hum  windspeed   cnt  \n",
       "0  0.363625  0.805833   0.160446   985  \n",
       "1  0.353739  0.696087   0.248539   801  \n",
       "2  0.189405  0.437273   0.248309  1349  \n",
       "3  0.212122  0.590435   0.160296  1562  \n",
       "4  0.229270  0.436957   0.186900  1600  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 数据降维\n",
    "# 去除第一列特征 instant\n",
    "# 去除第二列特征 dteday\n",
    "# 根据题目要求，需要预测cnt，而cnt = casual + registered，有数据冗余，故去除casual和registered特征\n",
    "\n",
    "data_FE = data.drop(['instant', 'dteday', 'casual', 'registered'], axis=1)\n",
    "\n",
    "data_FE.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(731, 12)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_FE.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 从原始数据中分离输入特征x和输出y\n",
    "y = data_FE['cnt'].values\n",
    "X = data_FE.drop('cnt', axis = 1)\n",
    "\n",
    "#用于后续显示权重系数对应的特征\n",
    "columns = X.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(584, 11)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#将数据分割训练数据与测试数据\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "# 随机采样20%的数据构建测试样本，其余作为训练样本\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=33, test_size=0.2)\n",
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "#发现各特征差异较大，需要进行数据标准化预处理\n",
    "#标准化的目的在于避免原始特征值差异过大，导致训练得到的参数权重不归一，无法比较各特征的重要性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "统一特征工程：\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/zhangwt/.local/lib/python3.6/site-packages/sklearn/utils/validation.py:475: DataConversionWarning: Data with input dtype int64 was converted to float64 by StandardScaler.\n",
      "  warnings.warn(msg, DataConversionWarning)\n"
     ]
    }
   ],
   "source": [
    "# 数据标准化\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "# 分别初始化对特征和目标值的标准化器\n",
    "ss_X = StandardScaler()\n",
    "ss_y = StandardScaler()\n",
    "\n",
    "print(\"统一特征工程：\")\n",
    "# 分别对训练和测试数据的特征以及目标值进行标准化处理\n",
    "X_train = ss_X.fit_transform(X_train)\n",
    "X_test = ss_X.transform(X_test)\n",
    "\n",
    "#对y做标准化不是必须\n",
    "#对y标准化的好处是不同问题的w差异不太大，同时正则参数的范围也有限\n",
    "y_train = ss_y.fit_transform(y_train.reshape(-1, 1))\n",
    "y_test = ss_y.transform(y_test.reshape(-1, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 确定模型类型\n",
    "## 最小二乘回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>columns</th>\n",
       "      <th>coef</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>yr</td>\n",
       "      <td>[0.5324153075686429]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>season</td>\n",
       "      <td>[0.30296485636420833]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>atemp</td>\n",
       "      <td>[0.2629254550745258]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>temp</td>\n",
       "      <td>[0.2222783379371304]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>weekday</td>\n",
       "      <td>[0.07004159630308604]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>workingday</td>\n",
       "      <td>[0.04409532963058758]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>holiday</td>\n",
       "      <td>[-0.02887596857342879]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>hum</td>\n",
       "      <td>[-0.06041596693577238]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>mnth</td>\n",
       "      <td>[-0.08635615066159785]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>windspeed</td>\n",
       "      <td>[-0.09222316307072898]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>weathersit</td>\n",
       "      <td>[-0.1933014064341719]</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       columns                    coef\n",
       "1           yr    [0.5324153075686429]\n",
       "0       season   [0.30296485636420833]\n",
       "8        atemp    [0.2629254550745258]\n",
       "7         temp    [0.2222783379371304]\n",
       "4      weekday   [0.07004159630308604]\n",
       "5   workingday   [0.04409532963058758]\n",
       "3      holiday  [-0.02887596857342879]\n",
       "9          hum  [-0.06041596693577238]\n",
       "2         mnth  [-0.08635615066159785]\n",
       "10   windspeed  [-0.09222316307072898]\n",
       "6   weathersit   [-0.1933014064341719]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 线性回归\n",
    "#class sklearn.linear_model.LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=1)\n",
    "from sklearn.linear_model import LinearRegression\n",
    "\n",
    "# 使用默认配置初始化\n",
    "lr = LinearRegression()\n",
    "\n",
    "# 训练模型参数\n",
    "lr.fit(X_train, y_train)\n",
    "\n",
    "# 预测\n",
    "y_test_pred_lr = lr.predict(X_test)\n",
    "y_train_pred_lr = lr.predict(X_train)\n",
    "\n",
    "\n",
    "# 看看各特征的权重系数，系数的绝对值大小可视为该特征的重要性\n",
    "fs = pd.DataFrame({\"columns\":list(columns), \"coef\":list((lr.coef_.T))})\n",
    "fs.sort_values(by=['coef'],ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The r2 score of LinearRegression on test is 0.8247836950496427\n",
      "The r2 score of LinearRegression on train is 0.7926559599511303\n"
     ]
    }
   ],
   "source": [
    "# 使用r2_score评价模型在测试集和训练集上的性能，并输出评估结果\n",
    "#测试集\n",
    "print('The r2 score of LinearRegression on test is', r2_score(y_test, y_test_pred_lr))\n",
    "#训练集\n",
    "print('The r2 score of LinearRegression on train is', r2_score(y_train, y_train_pred_lr))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The RMSE score of LinearRegression on test is 0.42622192010434873\n",
      "The RMSE score of LinearRegression on train is 0.4553504584919946\n"
     ]
    }
   ],
   "source": [
    "# 使用RMSE评价模型在测试集和训练集上的性能，并输出评估结果\n",
    "#测试集\n",
    "print('The RMSE score of LinearRegression on test is', np.sqrt(mean_squared_error(y_test, y_test_pred_lr)))\n",
    "#训练集\n",
    "print('The RMSE score of LinearRegression on train is', np.sqrt(mean_squared_error(y_train, y_train_pred_lr)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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ePHFF5tdihpk1KhRTJo0iZaWll5vw5CWpAKsWbOGvffem8mTJxPRqC8/U7NkJhs3bmTNmjVMmTKl19vxdLckFeDFF19k3LhxBvQQERGMGzeuz2dGDGlJKoQBPbQ04nga0pIkFcpr0pJUoLa2gd/eiBEjmDp1Kps3b2bKlCl861vfYsyYMbu9rwsvvJAPfvCDHHnkkds9/81vfpOlS5fy5S9/ebe3CTB69Gg2bdpU17ozZ87kqquuorW1ddtzS5cu5brrruPqq6/u1f6bwZ60JAmAV77ylSxfvpyHH36YsWPHcs011/RqO9dee+1OAV2C1tbWfg/oLVu2NHR7hrQkaSczZsxg7dq12+avvPJKjj/+eI455hg+9alPAfD8888ze/Zsjj32WI4++mgWLVoE1HqxHbeA/sY3vsFhhx3GCSecwD333LNte+effz633HLLtvnRo0cDsGnTJmbNmsVxxx3H1KlTue2223aqbd26dZx88slMmzaNo48+mh/96Ed1tWnJkiWcfvrpALS1tXHBBRcwc+ZMDjnkkO3C+/rrr+eEE05g2rRpvPe9790WvJdccgmtra0cddRR294DqN3y+vLLL+e4447j5ptvrquWenm6W5K0nS1btrB48WLmz58PwB133MHKlSu57777yEzOOOMM7r77btrb2znwwAP5/ve/D8Azzzyz3XbWrVvHpz71KZYtW8a+++7LW97yFqZPn77LfY8aNYpbb72VffbZh6eeeooTTzyRM844Y7tBWN/+9rc59dRTueKKK9iyZQsvvPBCr9r52GOPcdddd/Hcc8/xhje8gUsuuYRVq1axaNEi7rnnHlpaWrj00ku54YYbOO+88/jsZz/L2LFj2bJlC7NmzeLBBx/kmGOOAWDcuHHcf//9vapjVwxpSRIAv//975k2bRpr167liCOO4O1vfztQC+k77rhjW8Bu2rSJlStXctJJJ/GhD32Iyy+/nNNPP52TTjppu+3de++9zJw5k/Hja1/4dNZZZ/HLX/5ylzVkJh//+Me5++672WOPPVi7di3r169n//3337bO8ccfzwUXXMDLL7/M3LlzmTZtWq/aO3v2bPbcc0/23HNPJkyYwPr161m8eDHLli3j+OOP3/aeTJgwAYCbbrqJBQsWsHnzZtatW8ejjz66LaTPOuusXtXQE093S5KA/7wmvXr1ajJz2zXp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\n",
      "text/plain": [
       "<Figure size 504x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#在训练集上观察预测残差的分布，看是否符合模型假设：噪声为0均值的高斯噪声\n",
    "f, ax = plt.subplots(figsize=(7, 5)) \n",
    "f.tight_layout() \n",
    "ax.hist(y_train - y_train_pred_lr,bins=40, label='Residuals Linear', color='b', alpha=.5); \n",
    "ax.set_title(\"Histogram of Residuals\") \n",
    "ax.legend(loc='best');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 288x216 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#还可以观察预测值与真值的散点图\n",
    "plt.figure(figsize=(4, 3))\n",
    "plt.scatter(y_train, y_train_pred_lr)\n",
    "plt.plot([-3, 3], [-3, 3], '--k')   #数据已经标准化，3倍标准差即可\n",
    "plt.axis('tight')\n",
    "plt.xlabel('True cnt')\n",
    "plt.ylabel('Predicted cnt')\n",
    "plt.tight_layout()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/zhangwt/.local/lib/python3.6/site-packages/sklearn/utils/validation.py:578: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n",
      "  y = column_or_1d(y, warn=True)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([ 0.30375489,  0.53228858, -0.08583943, -0.0286715 ,  0.06952039,\n",
       "        0.0445512 , -0.19299703,  0.22475279,  0.26196117, -0.05971091,\n",
       "       -0.09286239])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 线性模型，随机梯度下降优化模型参数\n",
    "# 随机梯度下降一般在大数据集上应用，其实本项目不适合用\n",
    "from sklearn.linear_model import SGDRegressor\n",
    "\n",
    "# 使用默认配置初始化线\n",
    "sgdr = SGDRegressor(max_iter=1000)\n",
    "\n",
    "# 训练：参数估计\n",
    "sgdr.fit(X_train, y_train)\n",
    "\n",
    "# 预测\n",
    "#sgdr_y_predict = sgdr.predict(X_test)\n",
    "\n",
    "sgdr.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The value of default measurement of SGDRegressor on test is 0.825064256235987\n",
      "The value of default measurement of SGDRegressor on train is 0.7926470154056451\n"
     ]
    }
   ],
   "source": [
    "# 使用SGDRegressor模型自带的评估模块(评价准则为r2_score)，并输出评估结果\n",
    "print('The value of default measurement of SGDRegressor on test is', sgdr.score(X_test, y_test))\n",
    "print('The value of default measurement of SGDRegressor on train is', sgdr.score(X_train, y_train))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "#这里由于样本数不多，SGDRegressor可能不如LinearRegression。 sklearn建议样本数超过10万采用SGDRegressor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The r2 score of RidgeCV on test is 0.8255386802660793\n",
      "The r2 score of RidgeCV on train is 0.7924313555119178\n",
      "The RMSE score of RidgeCV on test is 0.4253026602297717\n",
      "The RMSE score of RidgeCV on train is 0.4555970198410896\n"
     ]
    }
   ],
   "source": [
    "#岭回归／L2正则\n",
    "#class sklearn.linear_model.RidgeCV(alphas=(0.1, 1.0, 10.0), fit_intercept=True, \n",
    "#                                  normalize=False, scoring=None, cv=None, gcv_mode=None, \n",
    "#                                  store_cv_values=False)\n",
    "from sklearn.linear_model import  RidgeCV\n",
    "\n",
    "#设置超参数（正则参数）范围\n",
    "alphas = [ 0.01, 0.1, 1, 10,100]\n",
    "#n_alphas = 20\n",
    "#alphas = np.logspace(-5,2,n_alphas)\n",
    "\n",
    "#生成一个RidgeCV实例\n",
    "ridge = RidgeCV(alphas=alphas, cv=5)  \n",
    "\n",
    "#模型训练\n",
    "ridge.fit(X_train, y_train)    \n",
    "\n",
    "#预测\n",
    "y_test_pred_ridge = ridge.predict(X_test)\n",
    "y_train_pred_ridge = ridge.predict(X_train)\n",
    "\n",
    "\n",
    "# 评估，使用r2_score评价模型在测试集和训练集上的性能\n",
    "print('The r2 score of RidgeCV on test is', r2_score(y_test, y_test_pred_ridge))\n",
    "print('The r2 score of RidgeCV on train is', r2_score(y_train, y_train_pred_ridge))\n",
    "\n",
    "# 评估，使用RMSE评价模型在测试集和训练集上的性能\n",
    "print('The RMSE score of RidgeCV on test is', np.sqrt(mean_squared_error(y_test, y_test_pred_ridge)))\n",
    "print('The RMSE score of RidgeCV on train is', np.sqrt(mean_squared_error(y_train, y_train_pred_ridge)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "alpha is: 10\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>columns</th>\n",
       "      <th>coef_lr</th>\n",
       "      <th>coef_ridge</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>yr</td>\n",
       "      <td>[0.5324153075686429]</td>\n",
       "      <td>[0.5230344147953429]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>season</td>\n",
       "      <td>[0.30296485636420833]</td>\n",
       "      <td>[0.2820480638200214]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>atemp</td>\n",
       "      <td>[0.2629254550745258]</td>\n",
       "      <td>[0.2503444111106679]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>temp</td>\n",
       "      <td>[0.2222783379371304]</td>\n",
       "      <td>[0.2342001499198519]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>weekday</td>\n",
       "      <td>[0.07004159630308604]</td>\n",
       "      <td>[0.06765302057283523]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>workingday</td>\n",
       "      <td>[0.04409532963058758]</td>\n",
       "      <td>[0.04372137355139595]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>holiday</td>\n",
       "      <td>[-0.02887596857342879]</td>\n",
       "      <td>[-0.02975845859934602]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>hum</td>\n",
       "      <td>[-0.06041596693577238]</td>\n",
       "      <td>[-0.06206158987872578]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>mnth</td>\n",
       "      <td>[-0.08635615066159785]</td>\n",
       "      <td>[-0.06677593980191822]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>windspeed</td>\n",
       "      <td>[-0.09222316307072898]</td>\n",
       "      <td>[-0.09274902100980817]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>weathersit</td>\n",
       "      <td>[-0.1933014064341719]</td>\n",
       "      <td>[-0.1899046605665245]</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       columns                 coef_lr              coef_ridge\n",
       "1           yr    [0.5324153075686429]    [0.5230344147953429]\n",
       "0       season   [0.30296485636420833]    [0.2820480638200214]\n",
       "8        atemp    [0.2629254550745258]    [0.2503444111106679]\n",
       "7         temp    [0.2222783379371304]    [0.2342001499198519]\n",
       "4      weekday   [0.07004159630308604]   [0.06765302057283523]\n",
       "5   workingday   [0.04409532963058758]   [0.04372137355139595]\n",
       "3      holiday  [-0.02887596857342879]  [-0.02975845859934602]\n",
       "9          hum  [-0.06041596693577238]  [-0.06206158987872578]\n",
       "2         mnth  [-0.08635615066159785]  [-0.06677593980191822]\n",
       "10   windspeed  [-0.09222316307072898]  [-0.09274902100980817]\n",
       "6   weathersit   [-0.1933014064341719]   [-0.1899046605665245]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#mse_mean = np.mean(ridge.cv_values_, axis = 0)\n",
    "#plt.plot(np.log10(alphas), mse_mean.reshape(len(alphas),1)) \n",
    "\n",
    "#这是为了标出最佳参数的位置，不是必须\n",
    "#plt.plot(np.log10(ridge.alpha_)*np.ones(3), [0.28, 0.29, 0.30])\n",
    "\n",
    "#plt.xlabel('log(alpha)')\n",
    "#plt.ylabel('mse')\n",
    "#plt.show()\n",
    "\n",
    "print ('alpha is:', ridge.alpha_)\n",
    "\n",
    "# 看看各特征的权重系数，系数的绝对值大小可视为该特征的重要性\n",
    "fs = pd.DataFrame({\"columns\":list(columns), \"coef_lr\":list((lr.coef_.T)), \"coef_ridge\":list((ridge.coef_.T))})\n",
    "fs.sort_values(by=['coef_lr'],ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The r2 score of LassoCV on test is 0.8249506614644996\n",
      "The r2 score of LassoCV on train is 0.7926370088771517\n",
      "The RMSE score of LassoCV on test is 0.42601879486568567\n",
      "The RMSE score of LassoCV on train is 0.45537126734440353\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/zhangwt/.local/lib/python3.6/site-packages/sklearn/linear_model/coordinate_descent.py:1094: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n",
      "  y = column_or_1d(y, warn=True)\n"
     ]
    }
   ],
   "source": [
    "#### Lasso／L1正则\n",
    "# class sklearn.linear_model.LassoCV(eps=0.001, n_alphas=100, alphas=None, fit_intercept=True, \n",
    "#                                    normalize=False, precompute=’auto’, max_iter=1000, \n",
    "#                                    tol=0.0001, copy_X=True, cv=None, verbose=False, n_jobs=1,\n",
    "#                                    positive=False, random_state=None, selection=’cyclic’)\n",
    "from sklearn.linear_model import LassoCV\n",
    "\n",
    "#设置超参数搜索范围\n",
    "#alphas = [ 0.01, 0.1, 1, 10,100]\n",
    "\n",
    "#生成一个LassoCV实例\n",
    "#lasso = LassoCV(alphas=alphas)  \n",
    "lasso = LassoCV(cv=5)  \n",
    "\n",
    "#训练（内含CV）\n",
    "lasso.fit(X_train, y_train)  \n",
    "\n",
    "#测试\n",
    "y_test_pred_lasso = lasso.predict(X_test)\n",
    "y_train_pred_lasso = lasso.predict(X_train)\n",
    "\n",
    "\n",
    "# 评估，使用r2_score评价模型在测试集和训练集上的性能\n",
    "print('The r2 score of LassoCV on test is', r2_score(y_test, y_test_pred_lasso))\n",
    "print('The r2 score of LassoCV on train is', r2_score(y_train, y_train_pred_lasso))\n",
    "\n",
    "# 评估，使用RMSE评价模型在测试集和训练集上的性能\n",
    "print('The RMSE score of LassoCV on test is', np.sqrt(mean_squared_error(y_test, y_test_pred_lasso)))\n",
    "print('The RMSE score of LassoCV on train is', np.sqrt(mean_squared_error(y_train, y_train_pred_lasso)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "alpha is: 0.001010967178720681\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>columns</th>\n",
       "      <th>coef_lr</th>\n",
       "      <th>coef_ridge</th>\n",
       "      <th>coef_lasso</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>yr</td>\n",
       "      <td>[0.5324153075686429]</td>\n",
       "      <td>[0.5230344147953429]</td>\n",
       "      <td>0.531387</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>season</td>\n",
       "      <td>[0.30296485636420833]</td>\n",
       "      <td>[0.2820480638200214]</td>\n",
       "      <td>0.296439</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>atemp</td>\n",
       "      <td>[0.2629254550745258]</td>\n",
       "      <td>[0.2503444111106679]</td>\n",
       "      <td>0.260981</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>temp</td>\n",
       "      <td>[0.2222783379371304]</td>\n",
       "      <td>[0.2342001499198519]</td>\n",
       "      <td>0.224096</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>weekday</td>\n",
       "      <td>[0.07004159630308604]</td>\n",
       "      <td>[0.06765302057283523]</td>\n",
       "      <td>0.068889</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>workingday</td>\n",
       "      <td>[0.04409532963058758]</td>\n",
       "      <td>[0.04372137355139595]</td>\n",
       "      <td>0.043401</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>holiday</td>\n",
       "      <td>[-0.02887596857342879]</td>\n",
       "      <td>[-0.02975845859934602]</td>\n",
       "      <td>-0.028504</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>hum</td>\n",
       "      <td>[-0.06041596693577238]</td>\n",
       "      <td>[-0.06206158987872578]</td>\n",
       "      <td>-0.059513</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>mnth</td>\n",
       "      <td>[-0.08635615066159785]</td>\n",
       "      <td>[-0.06677593980191822]</td>\n",
       "      <td>-0.079776</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>windspeed</td>\n",
       "      <td>[-0.09222316307072898]</td>\n",
       "      <td>[-0.09274902100980817]</td>\n",
       "      <td>-0.091277</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>weathersit</td>\n",
       "      <td>[-0.1933014064341719]</td>\n",
       "      <td>[-0.1899046605665245]</td>\n",
       "      <td>-0.192979</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       columns                 coef_lr              coef_ridge  coef_lasso\n",
       "1           yr    [0.5324153075686429]    [0.5230344147953429]    0.531387\n",
       "0       season   [0.30296485636420833]    [0.2820480638200214]    0.296439\n",
       "8        atemp    [0.2629254550745258]    [0.2503444111106679]    0.260981\n",
       "7         temp    [0.2222783379371304]    [0.2342001499198519]    0.224096\n",
       "4      weekday   [0.07004159630308604]   [0.06765302057283523]    0.068889\n",
       "5   workingday   [0.04409532963058758]   [0.04372137355139595]    0.043401\n",
       "3      holiday  [-0.02887596857342879]  [-0.02975845859934602]   -0.028504\n",
       "9          hum  [-0.06041596693577238]  [-0.06206158987872578]   -0.059513\n",
       "2         mnth  [-0.08635615066159785]  [-0.06677593980191822]   -0.079776\n",
       "10   windspeed  [-0.09222316307072898]  [-0.09274902100980817]   -0.091277\n",
       "6   weathersit   [-0.1933014064341719]   [-0.1899046605665245]   -0.192979"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mses = np.mean(lasso.mse_path_, axis = 1)\n",
    "plt.plot(np.log10(lasso.alphas_), mses) \n",
    "#plt.plot(np.log10(lasso.alphas_)*np.ones(3), [0.3, 0.4, 1.0])\n",
    "plt.xlabel('log(alpha)')\n",
    "plt.ylabel('mse')\n",
    "plt.show()    \n",
    "            \n",
    "print ('alpha is:', lasso.alpha_)\n",
    "\n",
    "# 看看各特征的权重系数，系数的绝对值大小可视为该特征的重要性\n",
    "fs = pd.DataFrame({\"columns\":list(columns), \"coef_lr\":list((lr.coef_.T)), \"coef_ridge\":list((ridge.coef_.T)), \"coef_lasso\":list((lasso.coef_.T))})\n",
    "fs.sort_values(by=['coef_lr'],ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The r2 score of LinearRegression on test is 0.8247836950496427\n",
      "The r2 score of LinearRegression on train is 0.7926559599511303\n",
      "The RMSE score of LinearRegression on test is 0.42622192010434873\n",
      "The RMSE score of LinearRegression on train is 0.4553504584919946\n",
      "The r2 score of RidgeCV on test is 0.8255386802660793\n",
      "The r2 score of RidgeCV on train is 0.7924313555119178\n",
      "The RMSE score of RidgeCV on test is 0.4253026602297717\n",
      "The RMSE score of RidgeCV on train is 0.4555970198410896\n",
      "The r2 score of LassoCV on test is 0.8249506614644996\n",
      "The r2 score of LassoCV on train is 0.7926370088771517\n",
      "The RMSE score of LassoCV on test is 0.42601879486568567\n",
      "The RMSE score of LassoCV on train is 0.45537126734440353\n"
     ]
    }
   ],
   "source": [
    "# 使用r2_score评价模型在测试集和训练集上的性能，并输出评估结果\n",
    "#测试集\n",
    "print('The r2 score of LinearRegression on test is', r2_score(y_test, y_test_pred_lr))\n",
    "#训练集\n",
    "print('The r2 score of LinearRegression on train is', r2_score(y_train, y_train_pred_lr))\n",
    "\n",
    "# 使用RMSE评价模型在测试集和训练集上的性能，并输出评估结果\n",
    "#测试集\n",
    "print('The RMSE score of LinearRegression on test is', np.sqrt(mean_squared_error(y_test, y_test_pred_lr)))\n",
    "#训练集\n",
    "print('The RMSE score of LinearRegression on train is', np.sqrt(mean_squared_error(y_train, y_train_pred_lr)))\n",
    "\n",
    "# 评估，使用r2_score评价模型在测试集和训练集上的性能\n",
    "print('The r2 score of RidgeCV on test is', r2_score(y_test, y_test_pred_ridge))\n",
    "print('The r2 score of RidgeCV on train is', r2_score(y_train, y_train_pred_ridge))\n",
    "\n",
    "# 评估，使用RMSE评价模型在测试集和训练集上的性能\n",
    "print('The RMSE score of RidgeCV on test is', np.sqrt(mean_squared_error(y_test, y_test_pred_ridge)))\n",
    "print('The RMSE score of RidgeCV on train is', np.sqrt(mean_squared_error(y_train, y_train_pred_ridge)))\n",
    "\n",
    "# 评估，使用r2_score评价模型在测试集和训练集上的性能\n",
    "print('The r2 score of LassoCV on test is', r2_score(y_test, y_test_pred_lasso))\n",
    "print('The r2 score of LassoCV on train is', r2_score(y_train, y_train_pred_lasso))\n",
    "\n",
    "# 评估，使用RMSE评价模型在测试集和训练集上的性能\n",
    "print('The RMSE score of LassoCV on test is', np.sqrt(mean_squared_error(y_test, y_test_pred_lasso)))\n",
    "print('The RMSE score of LassoCV on train is', np.sqrt(mean_squared_error(y_train, y_train_pred_lasso)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# The result is \n",
    "# ridge alpha is: 10.0\n",
    "# lasso alpha is: 0.001010967178720681\n",
    "#     coef_lasso                  coef_lr               coef_ridge     columns\n",
    "# 1     0.531387     [0.5324153075686437]     [0.5230344147953432]          yr\n",
    "# 0     0.296439    [0.30296485636420933]    [0.28204806382002373]      season\n",
    "# 8     0.260981    [0.26292545507452547]    [0.25034441111066436]       atemp\n",
    "# 7     0.224096    [0.22227833793713062]    [0.23420014991985533]        temp\n",
    "# 4     0.068889    [0.07004159630308626]    [0.06765302057283523]     weekday\n",
    "# 5     0.043401   [0.044095329630587224]    [0.04372137355139589]  workingday\n",
    "# 3    -0.028504   [-0.02887596857342884]  [-0.029758458599345977]     holiday\n",
    "# 9    -0.059513  [-0.060415966935772225]   [-0.06206158987872628]         hum\n",
    "# 2    -0.079776    [-0.0863561506615993]   [-0.06677593980192022]        mnth\n",
    "# 10   -0.091277   [-0.09222316307072867]   [-0.09274902100980824]   windspeed\n",
    "# 6    -0.192979    [-0.1933014064341721]   [-0.18990466056652372]  weathersit\n",
    "# The RMSE score of LinearRegression on test is 0.42622192010434884\n",
    "# The RMSE score of LinearRegression on train is 0.4553504584919946\n",
    "# The RMSE score of RidgeCV on test is 0.4253026602297717\n",
    "# The RMSE score of RidgeCV on train is 0.4555970198410895\n",
    "# The RMSE score of LassoCV on test is 0.42601879486568567\n",
    "# The RMSE score of LassoCV on train is 0.45537126734440353"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
